package geektime.jvm;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.util.TraceClassVisitor;

import java.io.PrintWriter;

import static org.objectweb.asm.Opcodes.*;

/**
 * 继承ClassVisitor类，访问者模式，用于修改和操作一些数据结构比较稳定的数据
 *      1. 基于事件驱动的接口，类似于xml的SAX接口，使用visitor模式，在访问到类的某个部分时进行回调
 *      2. 基于tree的接口，类似于xml的DOM接口，将类定义解析成tree
 */
public class PublicizeMethodAdapter extends ClassVisitor {
    private TraceClassVisitor tracer;

    // 构造方法
    public PublicizeMethodAdapter(ClassVisitor cv) {
        super(ASM4, cv);
        tracer = new TraceClassVisitor(new PrintWriter(System.out));
    }

    // 访问类中的方法，并将toUnsignedString0方法的修饰符修改为public
    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        // 将toUnsignedString0方法的权限修饰符修改为public
        if (name.equals("toUnsignedString0")) {
            System.out.println("Visiting the method: toUnsignedString0");
            return tracer.visitMethod(ACC_PUBLIC + ACC_STATIC, name, descriptor, signature, exceptions);
        }
        return super.visitMethod(access, name, descriptor, signature, exceptions);
    }

    @Override
    public void visitEnd() {
        tracer.visitEnd();
        System.out.println("Tracer end: " + tracer.p.getText());
    }
}
